package mcom.xmks.bluetooth.mesh;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.SwitchCompat;

import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;

import java.nio.charset.StandardCharsets;
import java.util.Locale;

import cn.wch.meshlib.core.MeshServer;
import cn.wch.meshlib.frame.MeshFrameAssemble;
import cn.wch.meshlib.frame.ack.AckFrame;
import cn.wch.meshlib.frame.ack.AckType;
import io.reactivex.Emitter;
import mcom.xmks.bluetooth.mesh.base.AbstractActivity;
import mcom.xmks.bluetooth.mesh.constant.IntentConstant;
import mcom.xmks.bluetooth.mesh.core.DataModel;
import mcom.xmks.bluetooth.mesh.dialog.AddNodeToGroupDialog;
import mcom.xmks.bluetooth.mesh.dialog.DialogUtil;
import mcom.xmks.bluetooth.mesh.storage.GroupStorageUtil;
import mcom.xmks.bluetooth.mesh.storage.StorageUtil;
import mcom.xmks.bluetooth.mesh.utils.ConvertUtil;
import mcom.xmks.bluetooth.mesh.utils.LogTool;

public class NodeDetailActivity extends AbstractActivity {
    private String nodeName=null;
    private int nodeAddress=-1;
    private Intent intent=null;
    private EditText etNodeData,editReceive;
    private SwitchCompat swHex;
    private Button btnSendData;
    @Override
    protected void setView() {
        setContentView(R.layout.activity_node_detail);
        intent=getIntent();
        if(intent.hasExtra(IntentConstant.NODE_NET_NAME)){
            nodeName=intent.getStringExtra(IntentConstant.NODE_NET_NAME);
        }
        nodeAddress=intent.getIntExtra(IntentConstant.NODE_NET_ADDRESS,-1);
        ActionBar actionBar = getSupportActionBar();
        if(actionBar!=null){
            if(nodeName!=null)
                actionBar.setTitle(nodeName);
            actionBar.setSubtitle(String.format(Locale.getDefault(),"节点地址:%04X",nodeAddress));
            actionBar.setHomeButtonEnabled(true);  //启用返回按钮
            actionBar.setDisplayHomeAsUpEnabled(true); //显示返回按钮
        }
        etNodeData=this.findViewById(R.id.etNodeData);
        editReceive=this.findViewById(R.id.editReceive);
        swHex=this.findViewById(R.id.swHex);
        btnSendData=this.findViewById(R.id.btnSendData);
    }
    @Override
    protected void initWidget() {
        MeshFrameAssemble.getInstance().setDataListener((data, len) -> {
           String hex= ConvertUtil.fromByteArray2HexString(data);
           String d=editReceive.getText().toString();
            editReceive.setText(d==null||d.length()==0?(hex):(d + "\n"+hex));
        });
        btnSendData.setOnClickListener(v -> {
            sendData();
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_node_detail,menu);
        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                break;
            case R.id.deleteNode:
                startDeleteNode();
                break;
            case R.id.addToGroup:
                addNodeToGroup();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LogTool.d("NodeDetailActivity destroy");
    }

    private void sendData(){
        if(nodeAddress<0){
            LogTool.d("node address is null or negative");
        }
        String dataString=etNodeData.getText().toString();
        if(dataString.isEmpty()){
            showToast("内容为空");
            return;
        }
        byte[] data;
        if(swHex.isChecked()){
            try {
                data=ConvertUtil.fromHexString2ByteArray(dataString);
            } catch (Exception e) {
                showToast(e.getMessage());
                return;
            }
        }else{
            data=dataString.getBytes(StandardCharsets.UTF_8);
        }
        /*
        DataModel.getInstance().rxjavaExecute(this, "正在发送数据", new DataModel.CallbackRunnable<>() {
            @Override
            public Boolean onRunnable() {
                try {
                   return MeshServer.getInstance().transferData(nodeAddress,data);//这里应该采用异步处理
                } catch (Exception e) {
                    return null;
                }
            }
        }, new Emitter<Boolean>() {
            @Override
            public void onNext(Boolean value) {
                showToast("发送数据"+(value?"成功" : "失败"));
            }
            @Override
            public void onError(Throwable e) {
                showToast(e.getMessage());
            }
            @Override
            public void onComplete() {
            }
        });
        */
        DataModel.getInstance().rxjavaExecute(this, "正在发送数据", new DataModel.EmitterCallback<Boolean>() {
            @Override
            public Boolean onRunnable() {
                try {
                    return MeshServer.getInstance().transferData(nodeAddress,data);//这里应该采用异步处理
                } catch (Exception e) {
                    return null;
                }
            }
            @Override
            public void onNext(Boolean value) {
                showToast("发送数据"+(value?"成功" : "失败"));
            }
            @Override
            public void onError(Throwable e) {
                showToast(e.getMessage());
            }
            @Override
            public void onComplete() {
            }
        });
    }
    private void startDeleteNode(){
        DialogUtil.getInstance().showSimpleDialog(this, "确定要删除此节点吗?",
                "删除", "取消", new DialogUtil.IResult() {
            @Override
            public void onContinue() {
                deleteNode();
            }
            @Override
            public void onCancel() {
            }
        });
    }
    private void addNodeToGroup(){
        AddNodeToGroupDialog dialog = new AddNodeToGroupDialog();
        dialog.setCancelable(false);
        dialog.setSelectGroupListener(address -> {
            LogTool.d(String.format("select group:0x", Integer.toHexString(address)));//address.toString(16)
           if(GroupStorageUtil.checkNodeHasExistInGroup(nodeAddress,address)){
               showToast("本节点已经存在于该Group中!");
           }else{
               realAddToGroup(nodeAddress,address);
           }
        });
        dialog.show(getSupportFragmentManager(),AddNodeToGroupDialog.class.getName());
    }

    /**
     * 删除节点
     */
    private void deleteNode(){
        if(nodeAddress<0){
            LogTool.d("node address is null or negative");
            return;
        }
        DataModel.getInstance().rxjavaExecute(this, "正在删除节点", new DataModel.CallbackRunnable<>() {
            @Override
            public AckFrame onRunnable() {
                try {
                    //应该采用异步操作，操作成功后对数据库数据进行操作
                    return MeshServer.getInstance().deleteNode(nodeAddress);
                } catch (Exception e) {
                    return null;
                }
            }
        }, new Emitter<AckFrame>() {
            @Override
            public void onNext(AckFrame value) {
                if (value.getAckType() == AckType.DELETE_NODE) {
                    showToast("删除节点" + ConvertUtil.getNodeHexString(value.getNetAddress()) + (value.getStatusCode() == 0 ? "成功" : "失败"));
                } else {
                    showToast("error ack");
                }
                if (value.getStatusCode() == 0) {
                    if (nodeAddress != -1) {
                        StorageUtil.deleteNode(nodeAddress);
                        GroupStorageUtil.removeNodeFromAllGroups(nodeAddress);
                    }
                    toNodeActivity();
                }
            }
            @Override
            public void onError(Throwable e) {
                showToast(e.getMessage());
            }
            @Override
            public void onComplete() {
            }
        });
        try {
            //应该采用异步操作，操作成功后对数据库数据进行操作
            MeshServer.getInstance().deleteNode(nodeAddress);
            StorageUtil.deleteNode(nodeAddress);
            GroupStorageUtil.removeNodeFromAllGroups(nodeAddress);
            toNodeActivity();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void toNodeActivity(){
        //startActivity(new Intent(this,MainActivity.class));
        Intent intent = new Intent();
        intent.putExtra(IntentConstant.REFRESH_LIST,true);
        setResult(RESULT_OK,intent);    //返回到主页面
        finish();
    }
    private void realAddToGroup(int nodeAddress,int groupAddress){
        DataModel.getInstance().rxjavaExecute(this, "节点订阅Group", new DataModel.CallbackRunnable() {
            @Override
            public Boolean onRunnable() {
                try {
                    return  MeshServer.getInstance().subscribe(nodeAddress, groupAddress);
                } catch (Exception e) {
                    showToast(e.getMessage());
                    return false;
                }
            }
        }, new Emitter<Boolean>() {
            @Override
            public void onNext(Boolean value) {
                showToast("订阅"+(value?"成功":"失败"));
                if(value){
                    GroupStorageUtil.addNodeToGroup(nodeAddress,groupAddress);
                }
            }
            @Override
            public void onError(Throwable e) {
                showToast(e.getMessage());
            }
            @Override
            public void onComplete() {
            }
        });
    }
}